#include <iic.h>
#include <STC8G.H>
#include <basic.h>
#include "ch455.h"

#define IIC_PORT P3
#define PIN_SDA_IDX_L 3
#define PIN_SCL_IDX_L 2

#define PIN_SDA_IDX_R 5
#define PIN_SCL_IDX_R 4

static i2c_handle_t xdata iic[2];
// 0-f
static uint8_t xdata bcdcode[16] = {0X3F, 0X06, 0X5B, 0X4F, 0X66, 0X6D, 0X7D, 0X07, 0X7F, 0X6F, 0X77, 0X7C, 0X58, 0X5E, 0X79, 0X71};
static uint8_t xdata bit_pos[4] = {0x68, 0x6a, 0x6c, 0x6e};

static void iic_init_();
static void segment_unit(uint8_t cube_idx, uint8_t cmd, uint8_t dat)
{
    i2c_handle_t *i2c_handler = &iic[cube_idx];
    i2c_start(i2c_handler);
    i2c_write_byte(i2c_handler, cmd);
    i2c_write_byte(i2c_handler, dat);
    i2c_stop(i2c_handler);
}
void ch455DigitalCubeInit()
{
    int i = 0;
    iic_init_();
    for (i = 0; i < 2; i++)
    {
        segment_unit(i, 0x48, 0x01); // set system mode
    }

    for (i = 0; i < 4; i++)
    {
        segment_unit(0, bit_pos[i], 0x00); // set system mode
        segment_unit(1, bit_pos[i], 0x00); // set system mode
    }
}
void ch455DigitalCubeWriteHex(uint8_t cube_index, uint8_t hex){
    segment_unit(cube_index / 4, bit_pos[cube_index % 4], hex); // set system mode
}
void ch455DigitalCubeDisplayUnit(uint8_t cube_index, uint8_t ch)
{
    ch455DigitalCubeWriteHex(cube_index, bcdcode[ch]);
}
void ch455DigitalCubeClear(uint8_t cube_index){
    segment_unit(cube_index / 4, bit_pos[cube_index % 4], 0x00); // set system mode
}


/////////////////////////////////////////

sbit SDA_l = IIC_PORT ^ PIN_SDA_IDX_L; // SDA引脚
sbit SCL_l = IIC_PORT ^ PIN_SCL_IDX_L; // SCL引脚

void sda_ctrl_l(bool isHigh)
{
    if (isHigh)
        SDA_l = 1; // 直接设置SDA引脚为高电平
    else
        SDA_l = 0; // 直接设置SDA引脚为低电平
}

void scl_ctrl_l(bool isHigh)
{
    if (isHigh)
        SCL_l = 1; // 直接设置SCL引脚为高电平
    else
        SCL_l = 0; // 直接设置SCL引脚为低电平
}

bool sda_read_l()
{
    return SDA_l; // 直接读取SDA引脚状态
}
sbit SDA_r = IIC_PORT ^ PIN_SDA_IDX_R; // 右侧SDA引脚
sbit SCL_r = IIC_PORT ^ PIN_SCL_IDX_R; // 右侧SCL引脚

void sda_ctrl_r(bool isHigh)
{
    if (isHigh)
        SDA_r = 1; // 直接设置右侧SDA引脚为高电平
    else
        SDA_r = 0; // 直接设置右侧SDA引脚为低电平
}

void scl_ctrl_r(bool isHigh)
{
    if (isHigh)
        SCL_r = 1; // 直接设置右侧SCL引脚为高电平
    else
        SCL_r = 0; // 直接设置右侧SCL引脚为低电平
}

bool sda_read_r()
{
    return SDA_r; // 直接读取右侧SDA引脚状态
}
void iic_init_()
{
    // 初始化左侧设备
    P3M1 &= ~((1 << PIN_SDA_IDX_L) | (1 << PIN_SCL_IDX_L));
    P3M0 |= ((1 << PIN_SDA_IDX_L) | (1 << PIN_SCL_IDX_L));

    iic[0].scl_ctrl = scl_ctrl_l;
    iic[0].sda_ctrl = sda_ctrl_l;
    iic[0].sda_read = sda_read_l;
    iic[0].addr = -1;

    // 初始化右侧设备
    P3M1 &= ~((1 << PIN_SDA_IDX_R) | (1 << PIN_SCL_IDX_R));
    P3M0 |= ((1 << PIN_SDA_IDX_R) | (1 << PIN_SCL_IDX_R));

    iic[1].scl_ctrl = scl_ctrl_r;
    iic[1].sda_ctrl = sda_ctrl_r;
    iic[1].sda_read = sda_read_r;
    iic[1].addr = -1;
}
